home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2004 April / Gamestar_61_2004-04_dvdb.iso / DVDStar / Editace / hltp.exe / {app} / Source Code / VirtualDub / Setup / main.cpp < prev    next >
C/C++ Source or Header  |  2003-10-01  |  35KB  |  1,176 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stddef.h>
  4. #include <stdarg.h>
  5. #include <malloc.h>
  6. #include <ctype.h>
  7. #include <crtdbg.h>
  8.  
  9. #include <windows.h>
  10. #include <commctrl.h>
  11.  
  12. #include "resource.h"
  13. #include "registry.h"
  14. #include "help.h"
  15. #include "helpfile.h"
  16.  
  17. HWND g_hwnd;
  18. HINSTANCE g_hInst; // current instance
  19. char szAppName[] = "VirtualDub Setup Class"; // The name of this application
  20. char szTitle[]   = ""; // The title bar text
  21. char g_szWinPath[MAX_PATH];
  22. char g_szProgPath[MAX_PATH];
  23. char g_szTempPath[MAX_PATH];
  24.  
  25. ///////////////////
  26.  
  27. BOOL Init(HINSTANCE, int);
  28. LRESULT APIENTRY WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
  29.  
  30. BOOL APIENTRY InstallAVIFileDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
  31. BOOL APIENTRY UninstallAVIFileDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
  32. BOOL APIENTRY RemoveSettingsDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
  33. BOOL APIENTRY DiskTestDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
  34. BOOL APIENTRY AboutDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
  35.  
  36. ///////////
  37.  
  38. int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  39.     LPSTR lpCmdLine, int nCmdShow )
  40. {
  41.     MSG msg;
  42.     char *lpszFilePart;
  43.  
  44.     ///////////
  45.  
  46.     if (!GetWindowsDirectory(g_szWinPath, sizeof g_szWinPath)) return FALSE;
  47.     if (!GetModuleFileName(NULL, g_szTempPath, sizeof g_szTempPath))
  48.         return FALSE;
  49.     if (!GetFullPathName(g_szTempPath, sizeof g_szProgPath, g_szProgPath, &lpszFilePart))
  50.         return FALSE;
  51.     *lpszFilePart=0;
  52.  
  53.     HelpSetPath();
  54.  
  55.     if (!Init(hInstance, nCmdShow)) return FALSE;
  56.  
  57.     // Main message loop.
  58.  
  59.     while (GetMessage(&msg, NULL, 0, 0)) {
  60. //        if (!IsDialogMessage(g_hwnd, &msg))
  61.         TranslateMessage(&msg);
  62.         DispatchMessage(&msg);
  63.     }
  64.  
  65.     return 0;
  66. }
  67.  
  68. ////////////////
  69.  
  70. BOOL Init(HINSTANCE hInstance, int nCmdShow)
  71. {
  72.     WNDCLASS  wc;
  73.  
  74.     // Register the window class for my window.                                                           */
  75.     wc.style = 0;                       // Class style.
  76.     wc.lpfnWndProc = (WNDPROC)WndProc; // Window procedure for this class.
  77.     wc.cbClsExtra = 0;                  // No per-class extra data.
  78.     wc.cbWndExtra = DLGWINDOWEXTRA;                  // No per-window extra data.
  79.     wc.hInstance = hInstance;           // Application that owns the class.
  80.     wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  81.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  82.     wc.hbrBackground = (HBRUSH)(COLOR_3DFACE+1); 
  83.     wc.lpszMenuName =  NULL;   // Name of menu resource in .RC file. 
  84.     wc.lpszClassName = szAppName; // Name used in call to CreateWindow.
  85.  
  86.     if (!RegisterClass(&wc)) return FALSE;
  87.  
  88.     g_hInst = hInstance; // Store instance handle in our global variable
  89.  
  90.     g_hwnd = CreateDialog(hInstance,MAKEINTRESOURCE(IDD_MAINWINDOW),NULL,(DLGPROC)NULL);
  91.  
  92.     if (!g_hwnd) {
  93.         return (FALSE);
  94.     }
  95.  
  96.     ShowWindow(g_hwnd, nCmdShow);
  97.     UpdateWindow(g_hwnd);
  98.  
  99.     return (TRUE);
  100. }
  101.  
  102. void PrintfWindowText(HWND hWnd, char *format, ...) {
  103.     char buf[256];
  104.     va_list val;
  105.  
  106.     va_start(val, format);
  107.     vsprintf(buf, format, val);
  108.     va_end(val);
  109.     SetWindowText(hWnd, buf);
  110. }
  111.  
  112. DWORD dwMainWindowHelpLookup[]={
  113.     IDC_BENCHMARK,        IDH_SETUP_BENCHMARK,
  114.     IDC_INSTALL,        IDH_SETUP_INSTALL,
  115.     IDC_UNINSTALL,        IDH_SETUP_UNINSTALL,
  116.     IDC_REMOVE,            IDH_SETUP_REMOVE,
  117.     0
  118. };
  119.  
  120. LRESULT APIENTRY WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  121. {
  122.  
  123.     switch (message) { 
  124.         case WM_DESTROY:
  125.             PostQuitMessage(0);
  126.             break;
  127.  
  128.         case WM_COMMAND:
  129.             switch(LOWORD(wParam)) {
  130.             case IDC_EXECUTE:
  131.                 if ((int)ShellExecute(hWnd, "open", "VirtualDub.exe", NULL, NULL, SW_SHOWNORMAL) <= 32)
  132.                     MessageBox(hWnd, "Couldn't launch VirtualDub.exe.", "Oops", MB_OK);
  133.                 break;
  134.             case IDC_BENCHMARK:
  135.                 DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DISKTEST_SETUP), hWnd, (DLGPROC)DiskTestDlgProc);
  136.                 break;
  137.             case IDC_INSTALL:
  138.                 DialogBox(g_hInst, MAKEINTRESOURCE(IDD_ATTEMPT), hWnd, (DLGPROC)InstallAVIFileDlgProc);
  139.                 break;
  140.             case IDC_UNINSTALL:
  141.                 DialogBox(g_hInst, MAKEINTRESOURCE(IDD_ATTEMPT), hWnd, (DLGPROC)UninstallAVIFileDlgProc);
  142.                 break;
  143.             case IDC_REMOVE:
  144.                 DialogBox(g_hInst, MAKEINTRESOURCE(IDD_ATTEMPT), hWnd, (DLGPROC)RemoveSettingsDlgProc);
  145.                 break;
  146.             case IDC_ABOUT:
  147.                 DialogBox(g_hInst, MAKEINTRESOURCE(IDD_ABOUT), hWnd, (DLGPROC)AboutDlgProc);
  148.                 break;
  149.             case IDCANCEL:
  150.                 DestroyWindow(hWnd);
  151.                 break;
  152.             }
  153.             break;
  154.  
  155.         case WM_HELP:
  156.             {
  157.                 HELPINFO *lphi = (HELPINFO *)lParam;
  158.  
  159.                 if (lphi->iContextType == HELPINFO_WINDOW)
  160.                     HelpPopupByID(hWnd, lphi->iCtrlId, dwMainWindowHelpLookup);
  161.             }
  162.             return TRUE;
  163.  
  164.         default:
  165.             return DefWindowProc(hWnd,message,wParam,lParam);
  166.     }
  167.     return (0);
  168. }
  169.  
  170. //////////////////////////////////////////////////////////////////////
  171.  
  172. void ListboxAddf(HWND hwndListbox, char *format, ...) {
  173.     char buf[256];
  174.     va_list val;
  175.  
  176.     va_start(val, format);
  177.     _vsnprintf(buf, sizeof buf, format, val);
  178.     va_end(val);
  179.     buf[(sizeof buf) - 1] = 0;
  180.  
  181.     SendMessage(hwndListbox, LB_ADDSTRING, 0, (LPARAM)buf);
  182. }
  183.  
  184. BOOL InstallFile(char *szSource, char *szDestFormat, ...) {
  185.     char szDest[MAX_PATH];
  186.     char szDestPath[MAX_PATH];
  187.     char szDestFile[MAX_PATH];
  188.     char *lpszDestFile;
  189.     char szCurInst[MAX_PATH];
  190.     char szTempFile[MAX_PATH];
  191.     DWORD dwFlags = VIFF_DONTDELETEOLD;
  192.     DWORD dwRet;
  193.     UINT uTmpLen;
  194.     char szFailure[256];
  195.     va_list val;
  196.  
  197.     va_start(val, szDestFormat);
  198.     vsprintf(szDest, szDestFormat, val);
  199.     va_end(val);
  200.  
  201.     if (!GetFullPathName(szDest, sizeof szDestPath, szDestPath, &lpszDestFile))
  202.         return FALSE;
  203.  
  204.     strcpy(szDestFile, lpszDestFile);
  205.     *lpszDestFile=0;
  206.  
  207.     do {
  208.         szTempFile[0]=0;
  209.         szCurInst[0]=0;
  210.         uTmpLen = sizeof szTempFile;
  211.         dwRet = VerInstallFile(dwFlags, szSource, szDestFile, g_szProgPath, szDestPath, szCurInst, szTempFile, &uTmpLen);
  212.  
  213.         if (dwRet & VIF_TEMPFILE) {
  214.             DeleteFile(szTempFile);
  215.             dwRet &= ~VIF_TEMPFILE;
  216.         }
  217.  
  218.         szFailure[0]=0;
  219.  
  220.         if (dwRet & (VIF_MISMATCH | VIF_DIFFTYPE))
  221.             sprintf(szFailure,    "The old %s doesn't look like a VirtualDub file.\n"
  222.                                 "If it belongs to another application, installing the new file may cause "
  223.                                 "the other app to stop functioning.\n"
  224.                                 "Install the new file only if you are sure or have a backup."
  225.                                 ,szDestFile);
  226.         else if (dwRet & VIF_SRCOLD)
  227.             sprintf(szFailure,    "%s is older than the %s being installed over.\n"
  228.                                 "You should install the older %s if you do not use other versions "
  229.                                 "of VirtualDub, since the newer file may be incompatible."
  230.                                 ,szSource,szDestFile);
  231.         else if (dwRet & VIF_WRITEPROT)
  232.             sprintf(szFailure,    "The %s being installed over has been marked read-only.\n"
  233.                                 "Override read-only attribute and install anyway?"
  234.                                 ,szDestFile);
  235.         else if (dwRet & VIF_FILEINUSE)
  236.             sprintf(szFailure,    "%s is in use.  It cannot be installed over right now.\n"
  237.                                 "If you have any copies of VirtualDub or any programs that "
  238.                                 "may be using VirtualDub's AVIFile handler, please close them "
  239.                                 "and then click OK to retry the operation."
  240.                                 ,szDestFile);
  241.         else if (dwRet & VIF_OUTOFSPACE)
  242.             sprintf(szFailure,    "Doh! We're out of space trying to write:\n\t%s\n\nCan you clear some up?"
  243.                                 ,szDest);
  244.         else if (dwRet & VIF_ACCESSVIOLATION)
  245.             sprintf(szFailure,    "Access violation.  Check with your administrator to see if you have "
  246.                                 "the appropriate permissions to write to \"%s\"."
  247.                                 ,szDest);
  248.         else if (dwRet & VIF_SHARINGVIOLATION)
  249.             sprintf(szFailure,    "Share violation; something else probably has %s open.  Try closing applications that "
  250.                                 "have the file open, and check permissions on network drives."
  251.                                 ,szDestFile);
  252.         else if (dwRet & VIF_CANNOTCREATE)
  253.             sprintf(szFailure,    "Couldn't create temporary file %s.\nTry again?", szTempFile);
  254.         else if (dwRet & VIF_CANNOTDELETE)
  255.             sprintf(szFailure,    "Couldn't delete temporary file %s.\nTry installing again?", szTempFile);
  256.         else if (dwRet & VIF_CANNOTDELETECUR)
  257.             sprintf(szFailure,    "Couldn't delete existing file \"%s\".\nTry installing again?", szDest);
  258.         else if (dwRet & VIF_CANNOTRENAME)
  259.             sprintf(szFailure,    "Deleted old file %s, but couldn't move %s into its place.\n"
  260.                                 "You should retry this operation.", szDestFile, szSource);
  261.         else if (dwRet & VIF_CANNOTREADSRC)
  262.             sprintf(szFailure,    "Couldn't read source file \"%s\".  Should I try again?"
  263.                                 ,szSource);
  264.         else if (dwRet & VIF_CANNOTREADDST)
  265.             sprintf(szFailure,    "Couldn't read destination file \"%s\".  I can try installing over it "
  266.                                 "anyway, though."
  267.                                 ,szDest);
  268.         else if (dwRet & VIF_OUTOFMEMORY)
  269.             sprintf(szFailure,    "Ran out of memory!  Try freeing some up.");
  270.         else if (dwRet)
  271.             sprintf(szFailure,    "Unidentified error copying:\n\t%s\n\t\tto\n\t%s\n\nTry forcing install?"
  272.                                 ,szSource
  273.                                 ,szDest);
  274.  
  275.         if (szFailure[0])
  276.             if (IDNO==MessageBox(NULL, szFailure, "Install error", MB_YESNO | MB_APPLMODAL))
  277.                 return FALSE;
  278.  
  279.         dwFlags |= VIFF_FORCEINSTALL;
  280.     } while(dwRet);
  281.  
  282.     return TRUE;
  283. }
  284.  
  285. BOOL InstallRegStr(HKEY hkBase, char *szKeyName, char *szName, char *szValue) {
  286.     char buf[256];
  287.  
  288.     if (!SetRegString(hkBase, szKeyName, szName, szValue)) {
  289.         sprintf(buf,"Couldn't set registry key %s\\%s",szKeyName,szName?szName:"(default)");
  290.         MessageBox(NULL, buf, "Install error", MB_OK);
  291.         return FALSE;
  292.     }
  293.  
  294.     return TRUE;
  295. }
  296.  
  297. BOOL InstallDeleteFile(char *szFileFormat, ...) {
  298.     char szFile[256];
  299.     va_list val;
  300.  
  301.     va_start(val, szFileFormat);
  302.     vsprintf(szFile, szFileFormat, val);
  303.     va_end(val);
  304.  
  305.     if (!DeleteFile(szFile))
  306.         if (GetLastError() != ERROR_FILE_NOT_FOUND)
  307.             return FALSE;
  308.  
  309.     return TRUE;
  310. }
  311.  
  312.  
  313. ///////////////////////////////////////
  314.  
  315. BOOL APIENTRY InstallAVIFileDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
  316.     switch(msg) {
  317.         case WM_INITDIALOG:
  318.             {
  319.                 HWND hwndListbox = GetDlgItem(hDlg, IDC_ACTIONLIST);
  320.  
  321.                 SetWindowText(hDlg, "Install AVIFile frameclient");
  322.  
  323.                 ListboxAddf(hwndListbox, "Copy VDREMOTE.DLL to %s\\SYSTEM\\VDREMOTE.DLL", g_szWinPath);
  324.                 ListboxAddf(hwndListbox, "Copy VDSRVLNK.DLL to %s\\SYSTEM\\VDSRVLNK.DLL", g_szWinPath);
  325.                 ListboxAddf(hwndListbox, "Add VDRemote class and AVIFile entries to Registry");
  326.             }
  327.             return TRUE;
  328.  
  329.         case WM_COMMAND:
  330.             switch(LOWORD(wParam)) {
  331.             case IDOK:
  332.                 if (    InstallFile("vdremote.dll","%s\\system\\vdremote.dll",g_szWinPath)
  333.                     &&    InstallFile("vdsvrlnk.dll","%s\\system\\vdsvrlnk.dll",g_szWinPath)
  334.                     &&    InstallRegStr(HKEY_CLASSES_ROOT,"CLSID\\{894288e0-0948-11d2-8109-004845000eb5}",NULL,"VirtualDub link handler")
  335.                     &&    InstallRegStr(HKEY_CLASSES_ROOT,"CLSID\\{894288e0-0948-11d2-8109-004845000eb5}\\InprocServer32",NULL,"vdremote.dll")
  336.                     &&    InstallRegStr(HKEY_CLASSES_ROOT,"CLSID\\{894288e0-0948-11d2-8109-004845000eb5}\\InprocServer32","ThreadingModel","Apartment")
  337.                     &&    InstallRegStr(HKEY_CLASSES_ROOT,"CLSID\\{894288e0-0948-11d2-8109-004845000eb5}\\InprocServer32\\AVIFile",NULL,"1")
  338.                     &&    InstallRegStr(HKEY_CLASSES_ROOT,"AVIFile\\Extensions\\VDR",NULL,"{894288e0-0948-11d2-8109-004845000eb5}")
  339.                     &&    InstallRegStr(HKEY_CLASSES_ROOT,"AVIFile\\RIFFHandlers\\VDRM",NULL,"{894288e0-0948-11d2-8109-004845000eb5}")
  340.                     )
  341.  
  342.                     MessageBox(hDlg, "AVIFile frameclient install successful.", "VirtualDub Setup", MB_OK);
  343.                 else
  344.                     MessageBox(hDlg, "AVIFile frameclient install failed.", "VirtualDub Setup", MB_OK);
  345.  
  346.                 EndDialog(hDlg, TRUE);
  347.                 return TRUE;
  348.             case IDCANCEL:
  349.                 EndDialog(hDlg, FALSE);
  350.                 return TRUE;
  351.             }
  352.     }
  353.     return FALSE;
  354. }
  355.  
  356. BOOL APIENTRY UninstallAVIFileDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
  357.     BOOL fSuccess;
  358.  
  359.     switch(msg) {
  360.         case WM_INITDIALOG:
  361.             {
  362.                 HWND hwndListbox = GetDlgItem(hDlg, IDC_ACTIONLIST);
  363.  
  364.                 SetWindowText(hDlg, "Uninstall AVIFile frameclient");
  365.  
  366.                 ListboxAddf(hwndListbox, "Delete %s\\SYSTEM\\VDREMOTE.DLL", g_szWinPath);
  367.                 ListboxAddf(hwndListbox, "Delete %s\\SYSTEM\\VDSRVLNK.DLL", g_szWinPath);
  368.                 ListboxAddf(hwndListbox, "Remove VDRemote class and AVIFile entries from Registry");
  369.             }
  370.             return TRUE;
  371.  
  372.         case WM_COMMAND:
  373.             switch(LOWORD(wParam)) {
  374.             case IDOK:
  375.                 fSuccess =  InstallDeleteFile("%s\\system\\vdremote.dll",g_szWinPath);
  376.                 fSuccess &= InstallDeleteFile("%s\\system\\vdsvrlnk.dll",g_szWinPath);
  377.  
  378.                 if (    ERROR_SUCCESS != RegDeleteKey(HKEY_CLASSES_ROOT,"Clsid\\{894288e0-0948-11d2-8109-004845000eb5}\\InprocServer32\\AVIFile")
  379.                     ||    ERROR_SUCCESS != RegDeleteKey(HKEY_CLASSES_ROOT,"Clsid\\{894288e0-0948-11d2-8109-004845000eb5}\\InprocServer32")
  380.                     ||    ERROR_SUCCESS != RegDeleteKey(HKEY_CLASSES_ROOT,"Clsid\\{894288e0-0948-11d2-8109-004845000eb5}")
  381.                     ||    ERROR_SUCCESS != RegDeleteKey(HKEY_CLASSES_ROOT,"AVIFile\\Extensions\\VDR")
  382.                     ||    ERROR_SUCCESS != RegDeleteKey(HKEY_CLASSES_ROOT,"AVIFile\\RIFFHandlers\\VDRM"))
  383.  
  384.                     MessageBox(hDlg, "Registry entries were in use.  Deinstall not successful.\n"
  385.                                     "\n"
  386.                                     "A partial installation now exists on your system.  Reinstall the AVIFile "
  387.                                     "handler to restore frameclient functionality, or close applications that may "
  388.                                     "be occupying the Registry entries and retry the deinstall."
  389.                                     ,"VirtualDub Setup",MB_OK);
  390.  
  391.                 else if (!fSuccess)
  392.                     MessageBox(hDlg, "DLL files were in use.  Deinstall not successful.\n"
  393.                                     "\n"
  394.                                     "A partial installation now exists on your system.  Reinstall the AVIFile "
  395.                                     "handler to restore frameclient functionality, or close applications that may "
  396.                                     "be occupying the shared DLLs and retry the deinstall."
  397.                                     ,"VirtualDub Setup",MB_OK);
  398.                 else
  399.                     MessageBox(hDlg, "AVIFile frameclient deinstall successful.", "VirtualDub Setup", MB_OK);
  400.  
  401.                 EndDialog(hDlg, TRUE);
  402.                 return TRUE;
  403.             case IDCANCEL:
  404.                 EndDialog(hDlg, FALSE);
  405.                 return TRUE;
  406.             }
  407.     }
  408.     return FALSE;
  409. }
  410.  
  411. ///////////////////////////////////////////////
  412.  
  413. void RemoveVirtualDubKeys(HWND hwndListbox) {
  414.     FILETIME ftModified;
  415.     int i;
  416.     LONG err;
  417.     char szKeyName[MAX_PATH];
  418.     char szErrorText[128];
  419.     DWORD dwKeyNameLen;
  420.  
  421.     SendMessage(hwndListbox, LB_RESETCONTENT, 0, 0);
  422.  
  423.     i=0;
  424.     for(;;) {
  425.         dwKeyNameLen = sizeof szKeyName;
  426.         err = RegEnumKeyEx(HKEY_USERS, i++, szKeyName, &dwKeyNameLen, 0, NULL, 0, &ftModified);
  427.  
  428.         if (err == ERROR_NO_MORE_ITEMS)
  429.             break;
  430.         else if (err == ERROR_SUCCESS) {
  431.             HKEY hkeyUser;
  432.             char *bp = szKeyName + strlen(szKeyName);
  433.             
  434.             err = RegOpenKeyEx(HKEY_USERS, szKeyName, 0, KEY_ALL_ACCESS, &hkeyUser);
  435.             if (err != ERROR_SUCCESS) {
  436.                 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, szErrorText, sizeof szErrorText, NULL);
  437.                 ListboxAddf(hwndListbox, "HKEY_USERS\\%s: %s", szKeyName, szErrorText);
  438.                 continue;
  439.             }
  440.  
  441.             strcpy(bp, "\\Software\\Freeware\\VirtualDub\\Capture");
  442.  
  443.             err = RegDeleteKey(HKEY_USERS,szKeyName);
  444.             if (err != ERROR_SUCCESS && err != ERROR_FILE_NOT_FOUND)
  445.                 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, szErrorText, sizeof szErrorText, NULL);
  446.             else
  447.                 strcpy(szErrorText, "Deleted");
  448.             ListboxAddf(hwndListbox, "HKEY_USERS\\%s: %s", szKeyName, szErrorText);
  449.  
  450.             strcpy(bp, "\\Software\\Freeware\\VirtualDub\\MRUList");
  451.  
  452.             err = RegDeleteKey(HKEY_USERS,szKeyName);
  453.             if (err != ERROR_SUCCESS && err != ERROR_FILE_NOT_FOUND)
  454.                 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, szErrorText, sizeof szErrorText, NULL);
  455.             else
  456.                 strcpy(szErrorText, "Deleted");
  457.             ListboxAddf(hwndListbox, "HKEY_USERS\\%s: %s", szKeyName, szErrorText);
  458.  
  459.             bp[29]=0;
  460.  
  461.             err = RegDeleteKey(HKEY_USERS,szKeyName);
  462.             if (err != ERROR_SUCCESS && err != ERROR_FILE_NOT_FOUND)
  463.                 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, szErrorText, sizeof szErrorText, NULL);
  464.             else
  465.                 strcpy(szErrorText, "Deleted");
  466.             ListboxAddf(hwndListbox, "HKEY_USERS\\%s: %s", szKeyName, szErrorText);
  467.  
  468.             RegCloseKey(hkeyUser);
  469.         }
  470.     }
  471. }
  472.  
  473. BOOL APIENTRY RemoveSettingsDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
  474.     switch(msg) {
  475.         case WM_INITDIALOG:
  476.             {
  477.                 HWND hwndListbox = GetDlgItem(hDlg, IDC_ACTIONLIST);
  478.  
  479.                 SetWindowText(hDlg, "Remove VirtualDub preference data");
  480.  
  481.                 ListboxAddf(hwndListbox, "Remove HKEY_USERS\\*\\Software\\Freeware\\VirtualDub\\*");
  482.             }
  483.             return TRUE;
  484.  
  485.         case WM_COMMAND:
  486.             switch(LOWORD(wParam)) {
  487.             case IDOK:
  488.                 SetWindowText(GetDlgItem(hDlg, IDC_ACTION), "Results:");
  489.  
  490.                 RemoveVirtualDubKeys(GetDlgItem(hDlg, IDC_ACTIONLIST));
  491.  
  492.                 SetWindowText(GetDlgItem(hDlg, IDOK), "Retry");
  493.                 SetWindowText(GetDlgItem(hDlg, IDCANCEL), "Done");
  494.                 return TRUE;
  495.             case IDCANCEL:
  496.                 EndDialog(hDlg, FALSE);
  497.                 return TRUE;
  498.             }
  499.     }
  500.     return FALSE;
  501. }
  502.  
  503. ///////////////////////////////////////////////////////////////////////////
  504. //
  505. // disk test
  506. //
  507. ///////////////////////////////////////////////////////////////////////////
  508.  
  509. class DiskTestParameters {
  510. public:
  511.     LONG lFrameSize;
  512.     LONG lFrameCount;
  513.     LONG lFrameBuffers;
  514.     LONG lFrameRate;
  515.     LONG lDiskBuffer;
  516.     LONG lMicroSecPerFrame;
  517.     DWORD dwBufferMode;
  518. };
  519.  
  520. BOOL DiskTestCreateStruc(HWND hDlg, DiskTestParameters *dtp) {
  521.     BOOL fSuccess;
  522.     char buf[128], c;
  523.     double d;
  524.     long lWidth, lHeight, lDepth;
  525.  
  526.     SendMessage(GetDlgItem(hDlg, IDC_FRAME_SIZE), WM_GETTEXT, sizeof buf, (LPARAM)buf);
  527.  
  528.     ////
  529.  
  530.     if (3==sscanf(buf, "%ldx%ldx%ld", &lWidth, &lHeight, &lDepth))
  531.         dtp->lFrameSize = (lWidth*lDepth+31)/32 * 4 * lHeight;
  532.  
  533.     else if (2==sscanf(buf, "%ldx%ld", &lWidth, &lHeight))
  534.         dtp->lFrameSize = (lWidth+(lWidth&1))*lHeight*2;
  535.  
  536.     else if (2==sscanf(buf, "%ld%c", &lWidth, &c) && c=='k' || c=='K')
  537.         dtp->lFrameSize = lWidth*1024;        // kilobytes
  538.  
  539.     else if (1==sscanf(buf, "%ld", &lWidth))
  540.         dtp->lFrameSize = lWidth;        // well, bytes actually...
  541.  
  542.     ////
  543.  
  544.     if (dtp->lFrameSize < 16 || dtp->lFrameSize > 1048576) {
  545.         return FALSE;
  546.     }
  547.  
  548.     dtp->lFrameCount        = GetDlgItemInt(hDlg, IDC_FRAME_COUNT, &fSuccess, FALSE);
  549.     if (dtp->lFrameCount < 1 || dtp->lFrameCount > 89478400) {
  550.         return FALSE;
  551.     }
  552.  
  553.     dtp->lFrameBuffers    = GetDlgItemInt(hDlg, IDC_FRAME_BUFFERS, &fSuccess, FALSE);
  554.     if (dtp->lFrameBuffers < 16 || dtp->lFrameBuffers > 4096) {
  555.         return FALSE;
  556.     }
  557.  
  558.     dtp->lDiskBuffer        = GetDlgItemInt(hDlg, IDC_DISK_BUFFER, &fSuccess, FALSE);
  559.     if (dtp->lDiskBuffer < 64) {
  560.         return FALSE;
  561.     }
  562.  
  563.     SendMessage(GetDlgItem(hDlg, IDC_FRAME_RATE), WM_GETTEXT, sizeof buf, (LPARAM)buf);
  564.     if (1!=sscanf(buf, "%lf", &d) || d<0.01 || d>200.0) {
  565.         return FALSE;
  566.     }
  567.  
  568.     dtp->lMicroSecPerFrame = (long)((1000000.0 / d) + 0.5);
  569.  
  570.     dtp->dwBufferMode = 0;
  571.     if (IsDlgButtonChecked(hDlg, IDC_DISABLE_BUFFERING))
  572.         dtp->dwBufferMode = FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING;
  573.  
  574.     return TRUE;
  575. }
  576.  
  577. /////////////////
  578.  
  579. LONG buffers;
  580. LONG buffers_in_use;
  581. long drop_count;
  582. long burst_drop_count;
  583. long max_burst_drop_count;
  584. BOOL last_was_dropped;
  585. volatile long captured_frames;
  586.  
  587. void CALLBACK DiskTestTimerProc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2) {
  588.     if (buffers_in_use >= buffers) {
  589.         ++drop_count;
  590.  
  591.         if (!last_was_dropped) {
  592.             burst_drop_count = 0;
  593.         }
  594.  
  595.         ++burst_drop_count;
  596.         last_was_dropped = TRUE;
  597.     } else {
  598.         if (burst_drop_count > max_burst_drop_count)
  599.             max_burst_drop_count = burst_drop_count;
  600.  
  601.         InterlockedIncrement(&buffers_in_use);
  602.  
  603.         last_was_dropped = FALSE;
  604.     }
  605.  
  606.     ++captured_frames;
  607. }
  608.  
  609. BOOL APIENTRY DiskTestStatusDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
  610.     switch(msg) {
  611.     case WM_INITDIALOG:
  612.         return TRUE;
  613.  
  614.     case WM_COMMAND:
  615.         switch(LOWORD(wParam)) {
  616.         case IDCANCEL:
  617.             PostQuitMessage(0);
  618.             return TRUE;
  619.         }
  620.         break;
  621.     }
  622.     return FALSE;
  623. }
  624.  
  625. void DiskTestDoIt(HWND hDlg) {
  626.     DiskTestParameters dtp;
  627.     char szFileName[MAX_PATH];
  628.     char szErrorBuf[MAX_PATH];
  629.     HMMIO hmmio        = NULL;
  630.     UINT timerID    = 0;
  631.     HANDLE hFile    = INVALID_HANDLE_VALUE;
  632.     HWND hwndStatus = NULL;
  633.     char *framebuf    = NULL;
  634.     char *buffer    = NULL;
  635.     int drive;
  636.  
  637.     if (CB_ERR == (drive = SendDlgItemMessage(hDlg, IDC_DRIVE, CB_GETCURSEL, 0, 0)))
  638.         return;
  639.  
  640.     drive = SendDlgItemMessage(hDlg, IDC_DRIVE, CB_GETITEMDATA, drive, 0);
  641.     sprintf(szFileName,"%c:\\DISKTEST.BIN", drive+'A');
  642.  
  643.     if (!DiskTestCreateStruc(hDlg, &dtp)) return;
  644.  
  645.     dtp.lFrameSize += 8;
  646.  
  647.     try {
  648.         DWORD max_frames;
  649.         MMIOINFO mmioinfo;
  650.         BOOL updated = FALSE;
  651.         long max_buffer_point = 0;
  652.         LONG lTotalBytes=0;
  653.         HWND hwndFrameCount, hwndDropCount, hwndBurstCount, hwndMaxBuffers;
  654.         LONG perthousand;
  655.         LONG tsec;
  656.         MSG msg;
  657.         DWORD dwOpenMode;
  658.  
  659.         if (!(hwndStatus = CreateDialog(g_hInst, MAKEINTRESOURCE(IDD_DISKTEST), hDlg, (DLGPROC)DiskTestStatusDlgProc)))
  660.             throw "Umm, no status dialog.  Doh!";
  661.  
  662.         EnableWindow(hDlg, FALSE);
  663.  
  664.         hwndFrameCount    = GetDlgItem(hwndStatus, IDC_FRAMES);
  665.         hwndDropCount    = GetDlgItem(hwndStatus, IDC_DROPPED);
  666.         hwndBurstCount    = GetDlgItem(hwndStatus, IDC_BURST_DROP);
  667.         hwndMaxBuffers    = GetDlgItem(hwndStatus, IDC_MAX_BUFFERS);
  668.  
  669.         if (!(framebuf = (char *)malloc(dtp.lFrameSize)))
  670.             throw "Couldn't allocate frame buffer.";
  671.  
  672.         if (!(buffer = (char *)VirtualAlloc(NULL, dtp.lDiskBuffer*1024, MEM_COMMIT, PAGE_READWRITE)))
  673.             throw "Couldn't allocate disk buffer";
  674.  
  675.         SetPriorityClass((HANDLE)GetCurrentProcess(), HIGH_PRIORITY_CLASS);
  676.  
  677.         ///////////
  678.  
  679.         buffers = dtp.lFrameBuffers;
  680.         buffers_in_use = 0;
  681.         drop_count = 0;
  682.         burst_drop_count = max_burst_drop_count = 0;
  683.         last_was_dropped = FALSE;
  684.         captured_frames = 0;
  685.         max_frames = dtp.lFrameCount;
  686.  
  687.         ////////////
  688.  
  689.         dwOpenMode = CREATE_NEW;
  690.  
  691.         for(;;) {
  692.             char msgbuf[MAX_PATH + 64];
  693.  
  694.             hFile = CreateFile(
  695.                     szFileName,
  696.                     GENERIC_WRITE,
  697.                     0,
  698.                     NULL,
  699.                     dwOpenMode,
  700.                     FILE_ATTRIBUTE_NORMAL | dtp.dwBufferMode,
  701.                     NULL
  702.                     );
  703.  
  704.             if (hFile == INVALID_HANDLE_VALUE) {
  705.                 if (GetLastError() == ERROR_FILE_EXISTS) {
  706.                     sprintf(msgbuf, "File %s already exists.  Overwrite?", szFileName);
  707.                     if (IDYES != MessageBox(hDlg, msgbuf, "Disk test warning", MB_YESNO))
  708.                         throw NULL;
  709.  
  710.                     dwOpenMode = OPEN_ALWAYS;
  711.                 } else {
  712.                     strcpy(szErrorBuf, "Error opening file: '");
  713.                     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, szErrorBuf+22, (sizeof szErrorBuf)-22, NULL);
  714.                     strcat(szErrorBuf, "'");
  715.  
  716.                     throw szErrorBuf;
  717.                 }
  718.             } else
  719.                 break;
  720.  
  721.         }
  722.  
  723.         memset(&mmioinfo, 0, sizeof mmioinfo);
  724.         mmioinfo.fccIOProc    = FOURCC_DOS;
  725.         mmioinfo.cchBuffer    = dtp.lDiskBuffer*1024;
  726.         mmioinfo.pchBuffer    = buffer;
  727.         mmioinfo.adwInfo[0] = (DWORD)hFile;
  728.  
  729.         if (!(hmmio = mmioOpen(NULL, &mmioinfo, MMIO_WRITE /*| MMIO_ALLOCBUF*/)))
  730.             throw "Couldn't open test file.";
  731.  
  732.         if (!(timerID = timeSetEvent(
  733.                         (dtp.lMicroSecPerFrame+500)/1000,
  734.                         (dtp.lMicroSecPerFrame+500)/1000,
  735.                         DiskTestTimerProc,
  736.                         NULL,
  737.                         TIME_PERIODIC)))
  738.             throw "Unable to initialize timer.";
  739.  
  740.         while(captured_frames < max_frames) {
  741.             if (buffers_in_use) {
  742.                 updated = FALSE;
  743.  
  744.                 if (buffers_in_use > max_buffer_point) max_buffer_point = buffers_in_use;
  745.  
  746.                 if (dtp.lFrameSize != mmioWrite(hmmio, framebuf, dtp.lFrameSize))
  747.                     throw "I/O error";
  748.  
  749.                 lTotalBytes += dtp.lFrameSize;
  750.  
  751.                 InterlockedDecrement(&buffers_in_use);
  752.             } else {
  753.                 if (!updated) {
  754.                     updated = TRUE;
  755.                     PrintfWindowText(hwndFrameCount, "%d/%d ", captured_frames, dtp.lFrameCount);
  756.                     PrintfWindowText(hwndDropCount, "%d ", drop_count);
  757.                     PrintfWindowText(hwndBurstCount, "%d ", max_burst_drop_count);
  758.                     PrintfWindowText(hwndMaxBuffers, "%d/%d ", max_buffer_point, dtp.lFrameBuffers);
  759.                 }
  760.  
  761.                 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
  762.                     if (msg.message == WM_QUIT)
  763.                         throw (char *)NULL;
  764.  
  765.                     if (!IsDialogMessage(hwndStatus, &msg) && !IsDialogMessage(hDlg, &msg)) {
  766.                         TranslateMessage(&msg);
  767.                         DispatchMessage(&msg);
  768.                     }
  769.                 }
  770.             }
  771.         }
  772.  
  773.         if (last_was_dropped)
  774.             if (burst_drop_count > max_burst_drop_count)
  775.                 max_burst_drop_count = burst_drop_count;
  776.  
  777.         // round out write to next 2048 bytes
  778.  
  779.         lTotalBytes = -lTotalBytes & 2047;
  780.  
  781.         if (lTotalBytes)
  782.             if (lTotalBytes != mmioWrite(hmmio, framebuf, lTotalBytes))
  783.                 throw "I/O error";
  784.  
  785.         ////////////
  786.  
  787.         if (!drop_count)
  788.             SetWindowText(hwndStatus, "Test passed - no frames dropped.");
  789.         else
  790.             SetWindowText(hwndStatus, "Test failed - frames were dropped.");
  791.  
  792.         SetDlgItemText(hwndStatus, IDCANCEL, "Ok");
  793.  
  794.         perthousand = (drop_count * 1000 + dtp.lFrameCount - 1) / dtp.lFrameCount;
  795.         tsec = (LONG)(((__int64)captured_frames * dtp.lMicroSecPerFrame + (__int64)99999) / 100000);
  796.  
  797.         PrintfWindowText(hwndFrameCount, "%d (%d.%d s)", captured_frames, tsec/10, tsec%10);
  798.         PrintfWindowText(hwndDropCount, "%d (%d.%d%%)", drop_count, perthousand/10, perthousand%10);
  799.         PrintfWindowText(hwndBurstCount, "%d (%d ms)", max_burst_drop_count,
  800.                 MulDiv(max_burst_drop_count, dtp.lMicroSecPerFrame, 1000));
  801.         PrintfWindowText(hwndMaxBuffers, "%d/%d ", max_buffer_point, dtp.lFrameBuffers);
  802.  
  803.         while (GetMessage(&msg, NULL, 0, 0)) {
  804.             if (!IsDialogMessage(hwndStatus, &msg) && !IsDialogMessage(hDlg, &msg)) {
  805.                 TranslateMessage(&msg);
  806.                 DispatchMessage(&msg);
  807.             }
  808.         }
  809.  
  810.     } catch(char *s) {
  811.         if (s)
  812.             MessageBox(hDlg, s, "Disk Test Error", MB_OK | MB_ICONEXCLAMATION);
  813.     }
  814.  
  815.     SetPriorityClass((HANDLE)GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
  816.     if (timerID) timeKillEvent(timerID); timerID = 0;
  817.     if (hmmio) mmioClose(hmmio,MMIO_FHOPEN);
  818.     if (hFile != INVALID_HANDLE_VALUE) {
  819.         CloseHandle(hFile);
  820.         DeleteFile(szFileName);
  821.     }
  822.     if (buffer) VirtualFree(buffer, 0, MEM_RELEASE);
  823.     if (framebuf) free(framebuf);
  824.     if (hwndStatus) {
  825.         EnableWindow(hDlg, TRUE);
  826.         SetFocus(hDlg);
  827.         DestroyWindow(hwndStatus);
  828.     }
  829. }
  830.  
  831. void DiskTestDoIt2(HWND hDlg) {
  832.     char szFileName[MAX_PATH];
  833.     char szErrorBuf[MAX_PATH];
  834.     UINT timerID    = 0;
  835.     HANDLE hFile    = INVALID_HANDLE_VALUE;
  836.     HWND hwndStatus = NULL;
  837.     char *buffer    = NULL;
  838.     int drive;
  839.     long lDiskBuffer, lMaxBytes;
  840.     BOOL fSuccess;
  841.     DWORD dwBufferMode;
  842.  
  843.     if (CB_ERR == (drive = SendDlgItemMessage(hDlg, IDC_DRIVE, CB_GETCURSEL, 0, 0)))
  844.         return;
  845.  
  846.     drive = SendDlgItemMessage(hDlg, IDC_DRIVE, CB_GETITEMDATA, drive, 0);
  847.     sprintf(szFileName,"%c:\\DISKTEST.BIN", drive+'A');
  848.  
  849.     lDiskBuffer        = GetDlgItemInt(hDlg, IDC_DISK_BUFFER, &fSuccess, FALSE);
  850.     if (lDiskBuffer < 64)
  851.         lDiskBuffer = 64;
  852.  
  853.     lDiskBuffer <<= 10;
  854.  
  855.     lMaxBytes        = GetDlgItemInt(hDlg, IDC_TOTAL_SIZE, &fSuccess, FALSE);
  856.     lMaxBytes <<= 20;
  857.  
  858.     dwBufferMode = 0;
  859.     if (IsDlgButtonChecked(hDlg, IDC_DISABLE_BUFFERING))
  860.         dwBufferMode = FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING;
  861.  
  862.     try {
  863.         LONG lTotalBytes=0;
  864.         MSG msg;
  865.         DWORD dwOpenMode;
  866.         DWORD dwReadTimeStart, dwReadTimeEnd, dwWriteTimeStart, dwWriteTimeEnd;
  867.  
  868.         if (!(hwndStatus = CreateDialog(g_hInst, MAKEINTRESOURCE(IDD_DISKTEST2), hDlg, (DLGPROC)DiskTestStatusDlgProc)))
  869.             throw "Umm, no status dialog.  Doh!";
  870.  
  871.         EnableWindow(hDlg, FALSE);
  872.  
  873.         if (!(buffer = (char *)VirtualAlloc(NULL, lDiskBuffer, MEM_COMMIT, PAGE_READWRITE)))
  874.             throw "Couldn't allocate disk buffer";
  875.  
  876.         SetPriorityClass((HANDLE)GetCurrentProcess(), HIGH_PRIORITY_CLASS);
  877.  
  878.         ////////////
  879.  
  880.         dwOpenMode = CREATE_NEW;
  881.  
  882.         for(;;) {
  883.             char msgbuf[MAX_PATH + 64];
  884.  
  885.             hFile = CreateFile(
  886.                     szFileName,
  887.                     GENERIC_READ | GENERIC_WRITE,
  888.                     0,
  889.                     NULL,
  890.                     dwOpenMode,
  891.                     FILE_ATTRIBUTE_NORMAL | dwBufferMode,
  892.                     NULL
  893.                     );
  894.  
  895.             if (hFile == INVALID_HANDLE_VALUE) {
  896.                 if (GetLastError() == ERROR_FILE_EXISTS) {
  897.                     sprintf(msgbuf, "File %s already exists.  Overwrite?", szFileName);
  898.                     if (IDYES != MessageBox(hDlg, msgbuf, "Disk test warning", MB_YESNO))
  899.                         throw NULL;
  900.  
  901.                     dwOpenMode = OPEN_ALWAYS;
  902.                 } else {
  903.                     strcpy(szErrorBuf, "Error opening file: '");
  904.                     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, szErrorBuf+22, (sizeof szErrorBuf)-22, NULL);
  905.                     strcat(szErrorBuf, "'");
  906.  
  907.                     throw szErrorBuf;
  908.                 }
  909.             } else
  910.                 break;
  911.  
  912.         }
  913.  
  914.         while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
  915.             if (msg.message == WM_QUIT)
  916.                 throw (char *)NULL;
  917.  
  918.             if (!IsDialogMessage(hwndStatus, &msg) && !IsDialogMessage(hDlg, &msg)) {
  919.                 TranslateMessage(&msg);
  920.                 DispatchMessage(&msg);
  921.             }
  922.         }
  923.  
  924.         SetWindowText(hwndStatus, "Prewriting file...");
  925.         while(lTotalBytes < lMaxBytes) {
  926.             DWORD dwBytes = lMaxBytes - lTotalBytes;
  927.             DWORD dwActual;
  928.  
  929.             if (dwBytes > lDiskBuffer)
  930.                 dwBytes = lDiskBuffer;
  931.  
  932.             if (!WriteFile(hFile, buffer, dwBytes, &dwActual, NULL) || dwActual != dwBytes)
  933.                 throw "I/O error";
  934.  
  935.             lTotalBytes += dwBytes;
  936.         }
  937.         FlushFileBuffers(hFile);
  938.  
  939.         SetWindowText(hwndStatus, "Writing to file...");
  940.         SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
  941.         FlushFileBuffers(hFile);
  942.  
  943.         dwWriteTimeStart = GetTickCount();
  944.         lTotalBytes=0;
  945.         while(lTotalBytes < lMaxBytes) {
  946.             DWORD dwBytes = lMaxBytes - lTotalBytes;
  947.             DWORD dwActual;
  948.  
  949.             if (dwBytes > lDiskBuffer)
  950.                 dwBytes = lDiskBuffer;
  951.  
  952.             if (!WriteFile(hFile, buffer, dwBytes, &dwActual, NULL) || dwActual != dwBytes)
  953.                 throw "I/O error";
  954.  
  955.             lTotalBytes += dwBytes;
  956.         }
  957.         FlushFileBuffers(hFile);
  958.         dwWriteTimeEnd = GetTickCount();
  959.  
  960.         SetWindowText(hwndStatus, "Reading from file...");
  961.  
  962.         SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
  963.         FlushFileBuffers(hFile);
  964.  
  965.         dwReadTimeStart = GetTickCount();
  966.         lTotalBytes=0;
  967.         while(lTotalBytes < lMaxBytes) {
  968.             DWORD dwBytes = lMaxBytes - lTotalBytes, dwActual;
  969.  
  970.             if (dwBytes > lDiskBuffer)
  971.                 dwBytes = lDiskBuffer;
  972.  
  973.             if (!ReadFile(hFile, buffer, dwBytes, &dwActual, NULL) || dwActual != dwBytes)
  974.                 throw "I/O error";
  975.  
  976.             lTotalBytes += dwBytes;
  977.         }
  978.         FlushFileBuffers(hFile);
  979.         dwReadTimeEnd = GetTickCount();
  980.  
  981.         ////////////
  982.         HWND hwndWrite, hwndRead;
  983.  
  984.         SetWindowText(hwndStatus, "Test complete.");
  985.  
  986.         SetDlgItemText(hwndStatus, IDCANCEL, "Ok");
  987.  
  988.         hwndRead = GetDlgItem(hwndStatus, IDC_READ_SPEED);
  989.         hwndWrite = GetDlgItem(hwndStatus, IDC_WRITE_SPEED);
  990.  
  991.         if (dwReadTimeStart == dwReadTimeEnd)
  992.             SetWindowText(hwndRead, "(too fast to measure)");
  993.         else
  994.             PrintfWindowText(hwndRead , "%ldKB/s ", MulDiv(lMaxBytes>>10, 1000, dwReadTimeEnd-dwReadTimeStart));
  995.  
  996.         if (dwWriteTimeStart == dwWriteTimeEnd)
  997.             SetWindowText(hwndRead, "(too fast to measure)");
  998.         else
  999.             PrintfWindowText(hwndWrite, "%ldKB/s ", MulDiv(lMaxBytes>>10, 1000, dwWriteTimeEnd-dwWriteTimeStart));
  1000.  
  1001.         while (GetMessage(&msg, NULL, 0, 0)) {
  1002.             if (!IsDialogMessage(hwndStatus, &msg) && !IsDialogMessage(hDlg, &msg)) {
  1003.                 TranslateMessage(&msg);
  1004.                 DispatchMessage(&msg);
  1005.             }
  1006.         }
  1007.  
  1008.     } catch(char *s) {
  1009.         if (s)
  1010.             MessageBox(hDlg, s, "Disk Test Error", MB_OK | MB_ICONEXCLAMATION);
  1011.     }
  1012.  
  1013.     SetPriorityClass((HANDLE)GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
  1014.     if (hFile != INVALID_HANDLE_VALUE) {
  1015.         CloseHandle(hFile);
  1016.         DeleteFile(szFileName);
  1017.     }
  1018.     if (buffer) VirtualFree(buffer, 0, MEM_RELEASE);
  1019.     if (hwndStatus) {
  1020.         EnableWindow(hDlg, TRUE);
  1021.         SetFocus(hDlg);
  1022.         DestroyWindow(hwndStatus);
  1023.     }
  1024. }
  1025.  
  1026. ///////////////////////////////////////////////////
  1027.  
  1028. DWORD dwDiskTestInitDlgHelpLookup[]={
  1029.     IDC_FRAME_SIZE,                IDH_BENCHMARK_FRAME_SIZE,
  1030.     IDC_FRAME_COUNT,            IDH_BENCHMARK_FRAME_COUNT,
  1031.     IDC_FRAME_BUFFERS,            IDH_BENCHMARK_FRAME_BUFFERS,
  1032.     IDC_FRAME_RATE,                IDH_BENCHMARK_FRAME_RATE,
  1033.     IDC_DISK_BUFFER,            IDH_BENCHMARK_DISK_BUFFER,
  1034.     IDC_DATA_RATE,                IDH_BENCHMARK_DATA_RATE,
  1035.     IDC_BUFFERING_NONE,            IDH_BENCHMARK_BUFFERING,
  1036.     IDC_BUFFERING_COMBINEONLY,    IDH_BENCHMARK_BUFFERING,
  1037.     IDC_BUFFERING_FULL,            IDH_BENCHMARK_BUFFERING,
  1038.     0,
  1039. };
  1040.  
  1041. void DiskTestUpdateFields(HWND hDlg) {
  1042.     DiskTestParameters dtp;
  1043.  
  1044.     if (!DiskTestCreateStruc(hDlg, &dtp))
  1045.         SetDlgItemText(hDlg, IDC_DATA_RATE, "<unknown>");
  1046.     else
  1047.         SetDlgItemInt(hDlg, IDC_DATA_RATE,(LONG)(
  1048.             (((__int64)dtp.lFrameSize * 1000000 + dtp.lMicroSecPerFrame/2) / dtp.lMicroSecPerFrame + 1023) / 1024),
  1049.             FALSE);
  1050. }
  1051.  
  1052. void DiskTestInitDlg(HWND hDlg) {
  1053.     DWORD dwDriveMask = GetLogicalDrives();
  1054.     HWND hwndCombo = GetDlgItem(hDlg, IDC_DRIVE);
  1055.     char buf[256], szVolName[64];
  1056.     int i;
  1057.     BOOL fHaveSelection = FALSE;
  1058.  
  1059.     for(i=0; i<26; i++) {
  1060.         if (dwDriveMask & (1L<<i)) {
  1061.             UINT uiDriveType;
  1062.             char *lpszDesc;
  1063.             int index;
  1064.  
  1065.             sprintf(buf, "%c:\\", i+'A');
  1066.             uiDriveType = GetDriveType(buf);
  1067.  
  1068.             switch(uiDriveType) {
  1069.             case 1:                    continue;    // no root directory!?
  1070.             case DRIVE_CDROM:        continue;    // How do you capture to a CD-ROM?
  1071.             case DRIVE_REMOVABLE:    lpszDesc = "Removable disk";    break;
  1072.             case DRIVE_FIXED:        lpszDesc = "Hard disk";            break;
  1073.             case DRIVE_REMOTE:        lpszDesc = "Network drive";        break;
  1074.             case DRIVE_RAMDISK:        lpszDesc = "Ramdisk";            break;
  1075.             default:                lpszDesc = "";                    break;
  1076.             }
  1077.  
  1078.             if (uiDriveType==DRIVE_FIXED && GetVolumeInformation(buf, szVolName, sizeof szVolName, NULL, NULL, NULL, NULL, 0))
  1079.                 sprintf(buf, "%c: %s [%s]", i+'A', lpszDesc, szVolName);
  1080.             else
  1081.                 sprintf(buf, "%c: %s", i+'A', lpszDesc);
  1082.  
  1083.             index = SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM)buf);
  1084.  
  1085.             if (index != CB_ERR) {
  1086.                 SendMessage(hwndCombo, CB_SETITEMDATA, (WPARAM)index, i);
  1087.                 if (!fHaveSelection && (i>=2 || !(dwDriveMask>>(i+1)))) {
  1088.                     fHaveSelection = TRUE;
  1089.  
  1090.                     SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM)index, 0);
  1091.                 }
  1092.             }
  1093.         }
  1094.     }
  1095.  
  1096.     SetDlgItemText(hDlg, IDC_FRAME_SIZE, "320x240x16");
  1097.     SetDlgItemText(hDlg, IDC_FRAME_COUNT, "200");
  1098.     SetDlgItemText(hDlg, IDC_FRAME_BUFFERS, "50");
  1099.     SetDlgItemText(hDlg, IDC_FRAME_RATE, "15.000");
  1100.     SetDlgItemText(hDlg, IDC_DISK_BUFFER, "1024");
  1101.     SetDlgItemText(hDlg, IDC_TOTAL_SIZE, "50");
  1102.     DiskTestUpdateFields(hDlg);
  1103.  
  1104.     CheckDlgButton(hDlg, IDC_BUFFERING_NONE, BST_CHECKED);
  1105. }
  1106.  
  1107. BOOL APIENTRY DiskTestDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
  1108.     switch(msg) {
  1109.         case WM_INITDIALOG:
  1110.             DiskTestInitDlg(hDlg);
  1111.             return TRUE;
  1112.  
  1113.         case WM_COMMAND:
  1114.             switch(LOWORD(wParam)) {
  1115.             case IDC_FRAME_SIZE:
  1116.             case IDC_FRAME_COUNT:
  1117.             case IDC_FRAME_BUFFERS:
  1118.             case IDC_FRAME_RATE:
  1119.             case IDC_DISK_BUFFER:
  1120.                 if (HIWORD(wParam)==EN_UPDATE)
  1121.                     DiskTestUpdateFields(hDlg);
  1122.                 break;
  1123.             case IDOK:
  1124.                 DiskTestDoIt(hDlg);
  1125.                 return TRUE;
  1126.             case IDC_BENCHDISK:
  1127.                 DiskTestDoIt2(hDlg);
  1128.                 return TRUE;
  1129.             case IDCANCEL:
  1130.                 EndDialog(hDlg, FALSE);
  1131.                 return TRUE;
  1132.             }
  1133.             break;
  1134.  
  1135.         case WM_HELP:
  1136.             {
  1137.                 HELPINFO *lphi = (HELPINFO *)lParam;
  1138.  
  1139.                 if (lphi->iContextType == HELPINFO_WINDOW)
  1140.                     HelpPopupByID(hDlg, lphi->iCtrlId, dwDiskTestInitDlgHelpLookup);
  1141.             }
  1142.             return TRUE;
  1143.     }
  1144.     return FALSE;
  1145. }
  1146.  
  1147. ///////////////////////////////////////////////////////////////////////////
  1148. //
  1149. //    About...
  1150. //
  1151. ///////////////////////////////////////////////////////////////////////////
  1152.  
  1153. BOOL APIENTRY AboutDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
  1154.     switch(msg) {
  1155.         case WM_INITDIALOG:
  1156.             SetDlgItemText(hDlg, IDC_FINALS_SUCK,
  1157. #ifdef _DEBUG
  1158.                 "Debug build"
  1159. #else
  1160.                 "Release build"
  1161. #endif
  1162.                 " ("__DATE__" "__TIME__")");
  1163.  
  1164.             return TRUE;
  1165.  
  1166.         case WM_COMMAND:
  1167.             switch(LOWORD(wParam)) {
  1168.             case IDOK:
  1169.             case IDCANCEL:
  1170.                 EndDialog(hDlg, FALSE);
  1171.                 return TRUE;
  1172.             }
  1173.     }
  1174.     return FALSE;
  1175. }
  1176.